home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / mint / mint104s.zoo / mint.src / pipefs.c < prev    next >
C/C++ Source or Header  |  1993-03-08  |  26KB  |  1,061 lines

  1. /*
  2. Copyright 1991,1992 Eric R. Smith.
  3. Copyright 1992 Atari Corporation.
  4. All rights reserved.
  5.  */
  6.  
  7. /* simple pipefs.c */
  8.  
  9. #include "mint.h"
  10.  
  11. static int pipetime, pipedate;    /* root directory time/date stamp */
  12.  
  13. static long    ARGS_ON_STACK pipe_root    P_((int drv, fcookie *fc));
  14. static long    ARGS_ON_STACK pipe_lookup    P_((fcookie *dir, const char *name, fcookie *fc));
  15. static long    ARGS_ON_STACK pipe_getxattr    P_((fcookie *file, XATTR *xattr));
  16. static long    ARGS_ON_STACK pipe_chattr    P_((fcookie *file, int attrib));
  17. static long    ARGS_ON_STACK pipe_chown    P_((fcookie *file, int uid, int gid));
  18. static long    ARGS_ON_STACK pipe_chmode    P_((fcookie *file, unsigned mode));
  19. static long    ARGS_ON_STACK pipe_rmdir    P_((fcookie *dir, const char *name));
  20. static long    ARGS_ON_STACK pipe_remove    P_((fcookie *dir, const char *name));
  21. static long    ARGS_ON_STACK pipe_getname    P_((fcookie *root, fcookie *dir,
  22.                             char *pathname, int size));
  23. static long    ARGS_ON_STACK pipe_rename    P_((fcookie *olddir, char *oldname,
  24.                     fcookie *newdir, const char *newname));
  25. static long    ARGS_ON_STACK pipe_opendir    P_((DIR *dirh, int flags));
  26. static long    ARGS_ON_STACK pipe_readdir    P_((DIR *dirh, char *nm, int nmlen, fcookie *));
  27. static long    ARGS_ON_STACK pipe_rewinddir    P_((DIR *dirh));
  28. static long    ARGS_ON_STACK pipe_closedir    P_((DIR *dirh));
  29. static long    ARGS_ON_STACK pipe_pathconf    P_((fcookie *dir, int which));
  30. static long    ARGS_ON_STACK pipe_dfree    P_((fcookie *dir, long *buf));
  31. static long    ARGS_ON_STACK pipe_creat    P_((fcookie *dir, const char *name, unsigned mode,
  32.                     int attrib, fcookie *fc));
  33. static DEVDRV *    ARGS_ON_STACK pipe_getdev    P_((fcookie *fc, long *devsp));
  34.  
  35. static long    ARGS_ON_STACK pipe_open    P_((FILEPTR *f));
  36. static long    ARGS_ON_STACK pipe_write    P_((FILEPTR *f, const char *buf, long bytes));
  37. static long    ARGS_ON_STACK pipe_read    P_((FILEPTR *f, char *buf, long bytes));
  38. static long    ARGS_ON_STACK pipe_lseek    P_((FILEPTR *f, long where, int whence));
  39. static long    ARGS_ON_STACK pipe_ioctl    P_((FILEPTR *f, int mode, void *buf));
  40. static long    ARGS_ON_STACK pipe_datime    P_((FILEPTR *f, short *time, int rwflag));
  41. static long    ARGS_ON_STACK pipe_close    P_((FILEPTR *f, int pid));
  42. static long    ARGS_ON_STACK pipe_select    P_((FILEPTR *f, long p, int mode));
  43. static void    ARGS_ON_STACK pipe_unselect    P_((FILEPTR *f, long p, int mode));
  44.  
  45. DEVDRV pipe_device = {
  46.     pipe_open, pipe_write, pipe_read, pipe_lseek, pipe_ioctl, pipe_datime,
  47.     pipe_close, pipe_select, pipe_unselect
  48. };
  49.  
  50. /* ptys and pipes can share the same driver, for now */
  51. #define pty_device pipe_device
  52.  
  53. FILESYS pipe_filesys = {
  54.     (FILESYS *)0,
  55.     0,
  56.     pipe_root,
  57.     pipe_lookup, pipe_creat, pipe_getdev, pipe_getxattr,
  58.     pipe_chattr, pipe_chown, pipe_chmode,
  59.     nomkdir, pipe_rmdir, pipe_remove, pipe_getname, pipe_rename,
  60.     pipe_opendir, pipe_readdir, pipe_rewinddir, pipe_closedir,
  61.     pipe_pathconf, pipe_dfree,
  62.     nowritelabel, noreadlabel, nosymlink, noreadlink,
  63.     nohardlink, nofscntl, nodskchng
  64. };
  65.  
  66. /* size of pipes */
  67. #define PIPESIZ    4096        /* MUST be a multiple of 4 */
  68.  
  69. /* writes smaller than this are atomic */
  70. #define PIPE_BUF 1024        /* should be a multiple of 4 */
  71.  
  72. /* magic flag: indicates that nobody but the creator has opened this pipe */
  73. /* note: if this many processes open the pipe, we lose :-( */
  74. #define VIRGIN_PIPE    0x7fff
  75.  
  76. struct pipe {
  77.     int    readers;    /* number of readers of this pipe */
  78.     int    writers;    /* number of writers of this pipe */
  79.     int    head, tail;    /* pipe head, tail (head == tail for empty) */
  80.     long    rsel;        /* process that did select() for reads */
  81.     long    wsel;        /* process that did select() for writes */
  82.     char    buf[PIPESIZ];    /* pipe data */
  83. };
  84.  
  85. struct fifo {
  86.     char    name[NAME_MAX+1]; /* FIFO's name */
  87.     short    date, time;    /* date & time of last write */
  88.     short    dosflags;    /* DOS flags, e.g. FA_RDONLY, FA_HIDDEN */
  89.     ushort    mode;        /* file access mode, for XATTR */
  90.     ushort    uid, gid;    /* file owner; uid and gid */
  91.     short    flags;        /* various other flags (e.g. O_TTY) */
  92.     short    lockpid;    /* pid of locking process */
  93.     short    cursrate;    /* cursor flash rate for pseudo TTY's */
  94.     struct tty *tty;    /* tty struct for pseudo TTY's */
  95.     struct pipe *inp;    /* pipe for reads */
  96.     struct pipe *outp;    /* pipe for writes (0 if unidirectional) */
  97.     struct fifo *next;    /* link to next FIFO in list */
  98.     FILEPTR *open;        /* open file pointers for this fifo */
  99. } *rootlist;
  100.  
  101.  
  102. static long ARGS_ON_STACK 
  103. pipe_root(drv, fc)
  104.     int drv;
  105.     fcookie *fc;
  106. {
  107.     if (drv == PIPEDRV) {
  108.         fc->fs = &pipe_filesys;
  109.         fc->dev = drv;
  110.         fc->index = 0L;
  111.         return 0;
  112.     }
  113.     fc->fs = 0;
  114.     return EINTRN;
  115. }
  116.  
  117. static long ARGS_ON_STACK 
  118. pipe_lookup(dir, name, fc)
  119.     fcookie *dir;
  120.     const char *name;
  121.     fcookie *fc;
  122. {
  123.     struct fifo *b;
  124.  
  125.     TRACE(("pipe_lookup(%s)", name));
  126.  
  127.     if (dir->index != 0) {
  128.         DEBUG(("pipe_lookup(%s): bad directory", name));
  129.         return EPTHNF;
  130.     }
  131. /* special case: an empty name in a directory means that directory */
  132. /* so does "." */
  133.     if (!*name || (name[0] == '.' && name[1] == 0)) {
  134.         *fc = *dir;
  135.         return 0;
  136.     }
  137.  
  138. /* another special case: ".." could be a mount point */
  139.     if (!strcmp(name, "..")) {
  140.         *fc = *dir;
  141.         return EMOUNT;
  142.     }
  143.  
  144.     for (b = rootlist; b; b = b->next) {
  145.         if (!strnicmp(b->name, name, NAME_MAX)) {
  146.             fc->fs = &pipe_filesys;
  147.             fc->index = (long)b;
  148.             fc->dev = dir->dev;
  149.             return 0;
  150.         }
  151.     }
  152.     DEBUG(("pipe_lookup: name `%s' not found", name));
  153.     return EFILNF;
  154. }
  155.  
  156. static long ARGS_ON_STACK 
  157. pipe_getxattr(fc, xattr)
  158.     fcookie *fc;
  159.     XATTR *xattr;
  160. {
  161.     struct fifo *this;
  162.  
  163.     xattr->index = fc->index;
  164.     xattr->dev = fc->dev;
  165.     xattr->nlink = 1;
  166.     xattr->blksize = 1;
  167.  
  168.     if (fc->index == 0) {        /* root directory? */
  169.         xattr->uid = xattr->gid = 0;
  170.         xattr->mtime = xattr->atime = xattr->ctime = pipetime;
  171.         xattr->mdate = xattr->adate = xattr->cdate = pipedate;
  172.         xattr->mode = S_IFDIR | DEFAULT_DIRMODE;
  173.         xattr->attr = FA_DIR;
  174.         xattr->size = xattr->nblocks = 0;
  175.     } else {
  176.         this = (struct fifo *)fc->index;
  177.         xattr->uid = this->uid;
  178.         xattr->gid = this->gid;
  179.         xattr->mtime = xattr->atime = xattr->ctime = this->time;
  180.         xattr->mdate = xattr->adate = xattr->cdate = this->date;
  181.         xattr->mode = this->mode;
  182.         xattr->attr = this->dosflags;
  183.     /* note: fifo's that haven't been opened yet can be written to */
  184.         if (this->flags & O_HEAD) {
  185.             xattr->attr &= ~FA_RDONLY;
  186.         }
  187.  
  188.         xattr->nblocks = PIPESIZ;
  189.         if (this->dosflags & FA_SYSTEM) {    /* pseudo-tty */
  190.             xattr->size = PIPESIZ/4;
  191.         } else {
  192.             xattr->size = PIPESIZ;
  193.         }
  194.     }
  195.     return 0;
  196. }
  197.  
  198. static long ARGS_ON_STACK 
  199. pipe_chattr(fc, attrib)
  200.     fcookie *fc;
  201.     int attrib;
  202. {
  203.     UNUSED(fc); UNUSED(attrib);
  204.     return EACCDN;
  205. }
  206.  
  207. static long ARGS_ON_STACK 
  208. pipe_chown(fc, uid, gid)
  209.     fcookie *fc;
  210.     int uid, gid;
  211. {
  212.     struct fifo *this;
  213.  
  214.     if ((this = (struct fifo *)fc->index) == 0)
  215.         return EACCDN;
  216.  
  217.     this->uid = uid;
  218.     this->gid = gid;
  219.     return 0;
  220. }
  221.  
  222. static long ARGS_ON_STACK 
  223. pipe_chmode(fc, mode)
  224.     fcookie *fc;
  225.     unsigned mode;
  226. {
  227.     struct fifo *this;
  228.  
  229.     if ((this = (struct fifo *)fc->index) == 0)
  230.         return EACCDN;
  231.  
  232.     this->mode = (this->mode & S_IFMT) | (mode & ~S_IFMT);
  233.     return 0;
  234. }
  235.  
  236. static long ARGS_ON_STACK 
  237. pipe_rmdir(dir, name)
  238.     fcookie *dir;
  239.     const char *name;
  240. {
  241.     UNUSED(dir); UNUSED(name);
  242.  
  243. /* the kernel already checked to see if the file exists */
  244.     return EACCDN;
  245. }
  246.  
  247. static long ARGS_ON_STACK 
  248. pipe_remove(dir, name)
  249.     fcookie *dir;
  250.     const char *name;
  251. {
  252.     UNUSED(dir); UNUSED(name);
  253.  
  254. /* the kernel already checked to see if the file exists */
  255.     return EACCDN;
  256. }
  257.  
  258. static long ARGS_ON_STACK 
  259. pipe_getname(root, dir, pathname, size)
  260.     fcookie *root, *dir; char *pathname;
  261.     int size;
  262. {
  263.     UNUSED(root);
  264.     UNUSED(size);    /* BUG: we should support 'size' */
  265.  
  266.     if (dir->index == 0)
  267.         *pathname = 0;
  268.     else
  269.         strcpy(pathname, ((struct fifo *)dir->index)->name);
  270.     return 0;
  271. }
  272.  
  273. static long ARGS_ON_STACK 
  274. pipe_rename(olddir, oldname, newdir, newname)
  275.     fcookie *olddir;
  276.     char *oldname;
  277.     fcookie *newdir;
  278.     const char *newname;
  279. {
  280.     UNUSED(olddir); UNUSED(oldname);
  281.     UNUSED(newdir); UNUSED(newname);
  282.  
  283.     return EACCDN;
  284. }
  285.  
  286. static long ARGS_ON_STACK 
  287. pipe_opendir(dirh, flags)
  288.     DI